package com.xiaohang.springstudy.chapter1.utils;

/**
 * 第一步，设所有发送的参数数据为集合M（包含timestamp参数，毫秒单位），将集合M内非空参数值的参数按照参数名ASCII码从小到大排序（字典序），使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA。
 * 特别注意以下重要规则：
 * ◆ 参数名ASCII码从小到大排序（字典序）；
 * ◆ 如果参数的值为空不参与签名；
 * ◆ 参数名区分大小写；
 * ◆ 字段名和字段值都采用原始值，不进行URL 转义
 * 第二步，在stringA最后拼接上key得到stringSignTemp字符串：
 * key为事先设定的私钥，拼接格式为stringSignTemp = stringA + “&key=xxxx”， xxx即为秘钥值
 * <p>
 * <p>
 * <p>
 * 第三步，对stringSignTemp进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。
 * <p>
 * 在signValue前拼接orderId(后端分配), 最后得到sign=orderId+signValue
 * <p>
 * 第四部, 访问api,参数形式如下
 * <p>
 * key1=value1&key2=value2&timestamp=111111&sign=00001DIFHEKLDJ4
 **/

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class SecurityUtil {

    /**
     * 获取签名
     *
     * @param appId   分配的appId
     * @param orderId 分配的orderId 对应 appId
     * @param params  参数map
     * @return
     * @throws Exception 描述：加密函数
     */
    public static String getSign(String appId, String orderId, Map<String, String> params) throws Exception {
        StringBuilder sign = new StringBuilder(orderId);
        String paramStr = getParamStr(params);
        paramStr += "&key=" + appId;
        return sign.append(md5(paramStr)).toString().toUpperCase();
    }

    public static String getSignJson(String appId, String orderId, Map<String, String> params) throws Exception {
        StringBuilder sign = new StringBuilder(orderId);
        String paramStr = getParamJson(params);
        paramStr += "&key=" + appId;
        return sign.append(md5(paramStr)).toString().toUpperCase();
    }

    public static String md5(String str) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = md.digest(str.getBytes(Charset.forName("utf-8")));
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            String temp = Integer.toHexString(b & 0xff);
            if (temp.length() == 1) {
                temp = "0" + temp;
            }
            result.append(temp);
        }
        return result.toString();
    }


    public static void main(String[] args) throws Exception {
        Map<String, String> map = new HashMap<>();
//        long currentTimeMillis = System.currentTimeMillis();
/*        map.put("proIdSecret","NzM3NzsxMA==");
        map.put("bodyType",0 +"");
        String date=getSign("kdkj9*KJ98JKJ98JH8K78","00001",map);
    	String  urlstr="https://dev.jfh.com/hwapi/ys/v1/pro/getProMsg?"; //公共域名
    	String url=urlstr+date;
    	System.out.println("url:---"+url);*/

        map.put("proIdSecret", "NzM3NzsxMA==");
        map.put("bodyType", "0");
        map.put("timestamp", System.currentTimeMillis() + "");
        map.put("sign", SecurityUtil.getSign("kdkj9*KJ98JKJ98JH8K78", "00001", map));
        String url = "https://dev.jfh.com/hwapi/ys/v1/pro/getProMsg?";
        url = url + map.toString();
        System.out.println("url:---" + url);
    }

    public static String getParamStr(Map<String, String> params) {
        Set<String> keys = params.keySet();
        List<String> keyList = new ArrayList<>(keys);
        Collections.sort(keyList);
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String k : keyList) {
            String value = params.get(k);
            if (StringUtils.isBlank(value)) {
                continue;
            }
            if (first) {
                first = false;
            } else {
                sb.append("&");
            }
            if (StringUtils.isNotBlank(value)) {
                sb.append(k).append("=").append(value);
            }
        }
        return sb.toString();
    }

    public static String getParamJson(Map<String, String> params) {
        Set<String> keys = params.keySet();
        List<String> keyList = new ArrayList<>(keys);
        Collections.sort(keyList);
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String k : keyList) {
            String value = JSON.toJSONString(params.get(k));
            if (StringUtils.isBlank(value)) {
                continue;
            }
            if (first) {
                first = false;
            } else {
                sb.append("&");
            }
            if (StringUtils.isNotBlank(value)) {
                sb.append(k).append("=").append(value);
            }
        }
        return sb.toString();
    }
}
